﻿using System;
using System.ComponentModel;
using System.Linq;
using Loki.Commands;
using Loki.UI;
using Loki.Utils;
using Luna.Model.Configuration;
using Luna.Model.CRM;
using Luna.UI.Configuration;
using Luna.UI.Contacts;
using Luna.UI.CRM;

namespace Luna.UI
{
    public class MainViewModel : LunaContainerViewModel
    {
        #region StoreName

        private static PropertyChangedEventArgs _StoreNameChangedArgs = ObservableHelper.CreateChangedArgs<MainViewModel>(x => x.StoreName);

        private static PropertyChangingEventArgs _StoreNameChangingArgs = ObservableHelper.CreateChangingArgs<MainViewModel>(x => x.StoreName);

        private string _StoreName;

        public string StoreName
        {
            get
            {
                return _StoreName;
            }

            set
            {
                if (value != _StoreName)
                {
                    NotifyChanging(_StoreNameChangingArgs);
                    _StoreName = value;
                    NotifyChanged(_StoreNameChangedArgs);
                }
            }
        }

        #endregion StoreName

        public MainViewModel()
        {
            AddNew<OpenDocumentsViewModel>();
            AddNew<NavigationMenuViewModel>();

            Documents.Desactivate.Execute(null);
            Navigation.Activate.Execute(null);

            Init += MainViewModel_Init;
            Load += MainViewModel_Load;
            DisplayName = "Luna";

            AttachedModels = CreateViewModelCollection();
        }

        #region SearchActive

        private static PropertyChangedEventArgs _SearchActiveChangedArgs = ObservableHelper.CreateChangedArgs<MainViewModel>(x => x.SearchActive);

        private static PropertyChangingEventArgs _SearchActiveChangingArgs = ObservableHelper.CreateChangingArgs<MainViewModel>(x => x.SearchActive);

        private bool _SearchActive;

        public bool SearchActive
        {
            get
            {
                return _SearchActive;
            }

            set
            {
                if (value != _SearchActive)
                {
                    NotifyChanging(_SearchActiveChangingArgs);
                    _SearchActive = value;
                    NotifyChanged(_SearchActiveChangedArgs);
                }
            }
        }

        #endregion SearchActive

        public ConnectorConfigurationViewModel ConnectorConfiguration
        {
            get
            {
                return AttachedModels.OfType<ConnectorConfigurationViewModel>().SingleOrDefault();
            }

            set
            {
                AttachedModels.Add(value);
            }
        }

        public OpenDocumentsViewModel Documents
        {
            get
            {
                return SubModels.OfType<OpenDocumentsViewModel>().SingleOrDefault();
            }
        }

        public ApplicationMenuViewModel Menu
        {
            get
            {
                return AttachedModels.OfType<ApplicationMenuViewModel>().SingleOrDefault();
            }

            set
            {
                AttachedModels.Add(value);
            }
        }

        public NavigationMenuViewModel Navigation
        {
            get
            {
                return SubModels.OfType<NavigationMenuViewModel>().SingleOrDefault();
            }
        }

        protected LokiCollection<IViewModel> AttachedModels { get; private set; }

        private void Application_NewAccount_Execute(object P_Sender, CommandEventArgs e)
        {
            IAccount L_New = ApplicationModel.Create<IAccount>();
            ApplicationCommands.OPEN.Execute(L_New);
        }

        private void Application_NewCategory_Execute(object P_Sender, CommandEventArgs e)
        {
            Luna.Model.Budget.IEditableCategory L_New = ApplicationModel.Create<Luna.Model.Budget.IEditableCategory>();
            ApplicationCommands.OPEN.Execute(L_New);
        }

        private void Application_OpenAccount_CanExecute(object P_Sender, CanExecuteCommandEventArgs e)
        {
            e.CanExecute |= e.Parameter is IAccount;
        }

        private void Application_OpenAccount_Execute(object P_Sender, CommandEventArgs e)
        {
            ActivateOrAdd<AccountEditViewModel>(v => v.CurrentAccount = e.Parameter as IAccount);
        }

        private void Data_New_Execute(object P_Sender, CommandEventArgs e)
        {
            ApplicationModel.Configuration.New();
        }

        private void Data_Open_Execute(object P_Sender, CommandEventArgs e)
        {
            using (var L_OpenVM = new OpenFileViewModel())
            {
                L_OpenVM.Filter = "Bases de donnée luna (*.lunadata)|*.lunadata";
                if (ShowAsModal(L_OpenVM) ?? false)
                {
                    ApplicationModel.Configuration.Open(L_OpenVM.FileName);
                }
            }
        }

        private void Data_SaveAs_Execute(object P_Sender, CommandEventArgs e)
        {
            using (var L_SaveVM = new SaveFileViewModel())
            {
                L_SaveVM.DefaultExtension = ".lunadata";
                L_SaveVM.Filter = "Bases de donnée luna (*.lunadata)|*.lunadata";
                if (ShowAsModal(L_SaveVM) ?? false)
                {
                    ApplicationModel.Configuration.SaveAs(L_SaveVM.FileName);
                }
            }
        }

        private void MainViewModel_Init(object P_Sender, EventArgs e)
        {
            Commands.Handle(ApplicationCommands.DATA_SAVE_AS, Data_SaveAs_Execute);
            Commands.Handle(ApplicationCommands.DATA_OPEN, Data_Open_Execute);
            Commands.Handle(ApplicationCommands.DATA_NEW, Data_New_Execute);
            Commands.Handle(ApplicationCommands.SEARCH, Search_Open);

            Commands.Handle(ApplicationCommands.OPEN, Application_OpenAccount_CanExecute, Application_OpenAccount_Execute);

            //Commands.Handle(ApplicationCommands.NEW_ACCOUNT, Application_NewAccount_Execute);
            // Commands.Handle(ApplicationCommands.NEW_CATEGORY, Application_NewCategory_Execute);

            var L_Context = ApplicationModel.Configuration;

            this.WatchChange(L_Context.Current, x => x.CurrentFile, v => v.ViewModel_StoreDescriptorChanged);
        }

        private void MainViewModel_Load(object P_Sender, EventArgs e)
        {
            var L_Context = ApplicationModel.Get<IConfigurationService>();
            L_Context.New();
        }

        private void Search_Open(object P_Sender, EventArgs e)
        {
            SearchActive = !SearchActive;
        }

        private void ViewModel_StoreDescriptorChanged(object P_Sender, PropertyChangedEventArgs e)
        {
            StoreName = ApplicationModel.Configuration.Current.CurrentFile;
        }
    }
}